#include <avr/io.h>
#include <util/delay.h>

#define DDR_IN 0
#define DDR_OUT 1

#define PORT_SEL PORTB
#define PIN_SEL PINB
#define DDR_SEL DDRB

#define PORT_SDI PORTB
#define PIN_SDI PINB
#define DDR_SDI DDRB

#define PORT_SCK PORTB
#define PIN_SCK PINB
#define DDR_SCK DDRB

#define PORT_SDO PORTD
#define PIN_SDO PIND
#define DDR_SDO DDRD

#define DDR_DATA DDRB


#define LED_DDR DDRA
#define LED PORTA
#define TRIGG_PORT LED = ~LED

/***** PORTB ******/
#define RFXX_SCK 7// |
#define RFXX_SDI 5// |
#define RFXX_SEL 4// |
#define RFXX_DATA 1// |
#define PB0 0//--/


/***** PORTD ******/
#define RFXX_SDO 2//


#define SEL_OUTPUT() DDR_SEL |= (1<<RFXX_SEL)
#define HI_SEL() PORT_SEL|= (1<<RFXX_SEL)
#define LOW_SEL() PORT_SEL&=~(1<<RFXX_SEL)

#define SDI_OUTPUT() DDR_SDI |= (1<<RFXX_SDI)
#define HI_SDI() PORT_SDI|= (1<<RFXX_SDI)
#define LOW_SDI() PORT_SDI&=~(1<<RFXX_SDI)

#define SDO_INPUT() DDR_SDO&= ~(1<<RFXX_SDO)
#define SDO_HI() PIN_SDO&(1<<RFXX_SDO)


#define SCK_OUTPUT() DDR_SCK |= (1<<RFXX_SCK)
#define HI_SCK() PORT_SCK|= (1<<RFXX_SCK)
#define LOW_SCK() PORT_SCK&=~(1<<RFXX_SCK)

#define DATA_OUTPUT() DDR_DATA |= (1<<RFXX_DATA) 



void RFXX_PORT_INIT(void)
{
	HI_SEL();
	HI_SDI();
	LOW_SCK();
	SEL_OUTPUT();
	SDI_OUTPUT();
	SDO_INPUT();

	SCK_OUTPUT();
	DATA_OUTPUT(); 
}
unsigned int RFXX_WRT_CMD(unsigned int aCmd)
{
	unsigned char i;
	unsigned int temp;
	
	LOW_SCK();
	LOW_SEL();
	for(i=0;i<16;i++)
	{
		temp<<=1;

		if(SDO_HI())
		{
			temp|=0x0001;
		}	
	
		LOW_SCK();
		
		if(aCmd&0x8000)
		{
			HI_SDI();
		}
		else
		{
			LOW_SDI();
		}
		
		HI_SCK();
		
		aCmd<<=1;
	};
	
	LOW_SCK();
	HI_SEL();
	
	return(temp);
}
void RF02B_SEND(unsigned char aByte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		
			/*
		while(PINB&(1<<RFXX_SDO));//Polling nIRQ
		while(!(PINB&(1<<RFXX_SDO)));
		*/
		loop_until_bit_is_clear(PIND,RFXX_SDO);
		PORTA=0xff;
		loop_until_bit_is_set(PIND,RFXX_SDO);


		if(aByte&0x80)
		{
			PORTB|=(1<<RFXX_DATA);
		}
		else
		{
			PORTB&=~(1<<RFXX_DATA);
		}
		aByte<<=1;
	}
}

int main(void)
{
	unsigned int i,j,ChkSum;
	LED_DDR = 0xff;
	
	
	RFXX_PORT_INIT();
	RFXX_WRT_CMD(0xCC00);
	RFXX_WRT_CMD(0x9361);//868BAND,+/-90kHz
	
	RFXX_WRT_CMD(0xA640);//868MHz

	RFXX_WRT_CMD(0xD040);//RATE/2
	RFXX_WRT_CMD(0xC823);//4.8kbps
	
	RFXX_WRT_CMD(0xC220);//ENABLE BIT SYNC
	RFXX_WRT_CMD(0xC001);//CLOSE ALL except CLK
	

	DDRB|=(1<<RFXX_DATA);//SET DATA OUTPUT

	PORTB|=(1<<RFXX_DATA);

	
	while(1)
	{
		RFXX_WRT_CMD(0xC039);//START TX
		ChkSum=0;
		
		RF02B_SEND(0xAA);//PREAMBLE
		RF02B_SEND(0xAA);//PREAMBLE
		RF02B_SEND(0xAA);//PREAMBLE
		
		RF02B_SEND(0x2D);//HEAD HI BYTE
		RF02B_SEND(0xD4);//HEAD LOW BYTE
		RF02B_SEND(0x30);//DATA0
		
		ChkSum+=0x30;
		RF02B_SEND(0x31);//DATA1
		ChkSum+=0x31;
		
		RF02B_SEND(0x32);
		ChkSum+=0x32;
		RF02B_SEND(0x33);
		
		ChkSum+=0x33;
		RF02B_SEND(0x34);
		ChkSum+=0x34;
		
		RF02B_SEND(0x35);
		ChkSum+=0x35;
		RF02B_SEND(0x36);
		
		ChkSum+=0x36;
		RF02B_SEND(0x37);
		ChkSum+=0x37;
		
		RF02B_SEND(0x38);
		ChkSum+=0x38;
		RF02B_SEND(0x39);
		
		ChkSum+=0x39;
		RF02B_SEND(0x3A);
		ChkSum+=0x3A;
		
		RF02B_SEND(0x3B);
		ChkSum+=0x3B;
		RF02B_SEND(0x3C);
		
		ChkSum+=0x3C;
		RF02B_SEND(0x3D);
		ChkSum+=0x3D;
		
		RF02B_SEND(0x3E);
		ChkSum+=0x3E;
		RF02B_SEND(0x3F);//DATA15
		
		ChkSum+=0x3F;
		RF02B_SEND(ChkSum);//DATA16
		RF02B_SEND(0xAA);//DUMMY BYTE
		
		RFXX_WRT_CMD(0xC001);//CLOSE TX
		
		for(i=0;i<5000;i++)for(j=0;j<123;j++);
	}

	return 0;
}
